package metrics

import (
	"time"
)

// TickerAggrIndicator 定时聚合上报indicator
type TickerAggrIndicator struct {
	ch         chan IndicData
	indicators []IIndicator
}

// NewTickerAggrIndicator 指标上报器-日志
func NewTickerAggrIndicator(indicators ...IIndicator) *TickerAggrIndicator {
	st := &TickerAggrIndicator{
		ch:         make(chan IndicData, 16),
		indicators: indicators,
	}
	go st.bgReport()
	return st
}

func (ind *TickerAggrIndicator) bgReport() {
	store := map[string]IndicData{}
	ti := time.NewTicker(time.Second)
	for {
		select {
		case data := <-ind.ch:
			old, exist := store[data.Name]
			if !exist {
				store[data.Name] = data
				continue
			}

			store[data.Name] = old.Append(data)
			if store[data.Name].Time != old.Time {
				ind.report(old)
			}
		case <-ti.C:
			if len(store) == 0 {
				continue
			}
			for _, data := range store {
				if (time.Now().UnixMilli() - data.Time) > data.AggrScope.Milliseconds() {
					ind.report(data)
				}
			}

			store = make(map[string]IndicData, len(store))
		}
	}
}

func (ind *TickerAggrIndicator) report(data IndicData) {
	for _, v := range ind.indicators {
		v.Report(data)
	}
}

// Report 上报数据
func (ind *TickerAggrIndicator) Report(data IndicData) {
	ind.ch <- data
}
